Release 10.1A: OpenEdge Development:
Messaging and ESB


Achieving scalable server architecture with PTP queuing

The procedures example20.p (1 of 2) and example21.p (1 of 2) use PTP queuing to achieve scalable server architecture. Several instances of example20.p (1 of 2) send requests to a single JMS queue and receive replies from servers that run example21.p (1 of 2). You can add more instances to handle an increasing volume of requests.

To run example20.p and example21.p:

  1. Create the requestQueue queue using the SonicMQ Explorer.
  2. Run example20.p (1 of 2) to send requests to the requestQueue queue, as shown:
  3. example20.p
    /* Sends a request to a queue and receives a reply from the server. */ 
    DEFINE VARIABLE ptpsession AS HANDLE. 
    DEFINE VARIABLE consumerH AS HANDLE. 
    DEFINE VARIABLE requestH AS HANDLE. 
    DEFINE VARIABLE request AS CHAR. 
    /* Creates a session object. */ 
    RUN jms/ptpsession.p PERSISTENT SET ptpsession ("-H localhost -S 5162 "). 
    RUN setBrokerURL IN ptpsession ("localhost:2506"). 
    RUN beginSession IN ptpsession. 
    /* Create a text message */ 
    RUN createTextMessage IN ptpsession (OUTPUT requestH). 
    /* Creates a consumer for the reply  */ 
    RUN createMessageConsumer IN ptpsession ( 
                    THIS-PROCEDURE,    /* This proc will handle it */ 
                    "replyHandler",    /* name of internal procedure */ 
                    OUTPUT consumerH). 
    /* Start the reply receiving  */ 
    RUN startReceiveMessages IN ptpsession. 
    
    /* Loop forever. */ 
    REPEAT: 
      UPDATE request WITH FRAME f1 CENTERED. 
      RUN setText IN requestH (request). 
      /* Sends a request to the requestQueue and handles the reply in the  
         replyHandler internal procedure. */ 
      RUN requestReply IN ptpsession ( "requestQueue", 
                                       requestH, 
                                       ?, /* No reply selector. */ 
                                       consumerH, ?, ?, ?).  
      /* Wait for the reply. */ 
      WAIT-FOR u1 OF THIS-PROCEDURE. 
    END. 
    
    PROCEDURE replyHandler: 
    DEFINE INPUT PARAMETER replyH AS HANDLE. 
    DEFINE INPUT PARAMETER msgConsumerH AS HANDLE. 
    DEFINE OUTPUT PARAMETER responseH AS HANDLE. 
        /* Display the reply from the server. */ 
        DISPLAY "reply text: " DYNAMIC-FUNCTION('getText':U IN replyH)  
                                                FORMAT "X(30)". 
        RUN deleteMessage IN replyH. 
        APPLY "U1" TO THIS-PROCEDURE. 
    END. 
    

  4. Run example21.p (1 of 2) to receive requests from the requestQueue queue, execute them, and reply to the requester, as shown:
  5. example21.p
    /* This example implements a server who gets requests from a JMS queue, 
       executes the request, and replies to the requester. Run several 
       instances of this server and several instances of a client (example20) 
       to observe the scalability of this configuration. */ 
    DEFINE INPUT PARAMETER serverName AS CHAR. 
    DEFINE VARIABLE ptpsession AS HANDLE. 
    DEFINE VARIABLE consumerH AS HANDLE. 
    DEFINE VARIABLE replyMessage AS HANDLE. 
    /* Creates a session object. */ 
    RUN jms/ptpsession.p PERSISTENT SET ptpsession  
                                   ("-H localhost -S 5162 "). 
    RUN setBrokerURL IN ptpsession ("localhost:2506"). 
    RUN beginSession IN ptpsession. 
    /* Uses one message for all the replies. */ 
    RUN createTextMessage IN ptpsession (OUTPUT replyMessage). 
    /* receives requests from  the requestQueue */ 
    RUN createMessageConsumer IN ptpsession ( 
                     THIS-PROCEDURE,    /* This proc will handle it */ 
                     "requestHandler",  /* name of internal procedure */ 
                     OUTPUT consumerH). 
    RUN receiveFromQueue IN ptpsession (
                     "requestQueue",   /* request queue */ 
                     ?,                /* No message selector */ 
                     consumerH).       /* Handles the messages */ 
    /* Start receiving requests */ 
    RUN startReceiveMessages IN ptpsession. 
    /* Process requests forever. */ 
    RUN waitForMessages IN ptpsession ("inWait", THIS-PROCEDURE, ?). 
    
    PROCEDURE requestHandler: 
    DEFINE INPUT PARAMETER requestH AS HANDLE. 
    DEFINE INPUT PARAMETER msgConsumerH AS HANDLE. 
    DEFINE OUTPUT PARAMETER replyH AS HANDLE. 
    DEFINE VAR replyText AS CHAR. 
        /* Creates a reply message. The reply is sent automatically when 
           control returns to the 4GL-To-JMS implementation. 
        */ 
        replyText=serverName + " executed " + DYNAMIC-FUNCTION 
                                                 ('getText':U IN requestH). 
        RUN deleteMessage IN requestH. 
        replyH = replyMessage. 
        RUN setText IN replyH (replyText). 
    END. 
    
    FUNCTION inWait RETURNS LOGICAL. 
        RETURN true. 
    END. 
    


Copyright © 2005 Progress Software Corporation
www.progress.com
Voice: (781) 280-4000
Fax: (781) 280-4095